package com.shqcjd.generalplatformprojectclient.ui.activity;

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Handler;
import android.os.SystemClock;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.view.KeyEvent;
import android.view.SurfaceView;
import android.view.View;
import android.widget.CheckBox;
import android.widget.Chronometer;
import android.widget.CompoundButton;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.Toast;

import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;
import com.google.gson.Gson;
import com.orhanobut.logger.Logger;
import com.shqcjd.generalplatformprojectclient.R;
import com.shqcjd.generalplatformprojectclient.api.ApiService;
import com.shqcjd.generalplatformprojectclient.app.MyApp;
import com.shqcjd.generalplatformprojectclient.helper.rxjavahelper.RxObserver;
import com.shqcjd.generalplatformprojectclient.helper.rxjavahelper.RxResultHelper;
import com.shqcjd.generalplatformprojectclient.helper.rxjavahelper.RxSchedulersHelper;
import com.shqcjd.generalplatformprojectclient.model.ResponseData;
import com.shqcjd.generalplatformprojectclient.model.pojo.RemoteGuidanceBean;
import com.shqcjd.generalplatformprojectclient.ui.base.BaseActivity;
import com.shqcjd.generalplatformprojectclient.ui.base.BasePresenter;
import com.shqcjd.generalplatformprojectclient.util.PrefUtils;
import com.shqcjd.generalplatformprojectclient.widget.BadgeHelper;
import com.shqcjd.generalplatformprojectclient.widget.IconFontTextView;
import com.tbruyelle.rxpermissions2.RxPermissions;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import butterknife.BindView;
import butterknife.OnClick;
import es.dmoral.toasty.Toasty;
import io.agora.AgoraAPI;
import io.agora.AgoraAPIOnlySignal;
import io.agora.IAgoraAPI;
import io.agora.rtc.RtcEngine;
import io.agora.rtc.video.VideoCanvas;
import io.agora.rtc.video.VideoEncoderConfiguration;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;

public class RemoteGuidanceActivity extends BaseActivity implements MyApp.OnAgoraEngineInterface {
    private static final String LOG_TAG = RemoteGuidanceActivity.class.getSimpleName();
    private static final int PERMISSION_REQ_ID_RECORD_AUDIO = 22;
    private static final int PERMISSION_REQ_ID_CAMERA = PERMISSION_REQ_ID_RECORD_AUDIO + 1;
    private static final int PERMISSION_REQ_ID_STORAGE = PERMISSION_REQ_ID_CAMERA + 1;

    @BindView(R.id.if_add_user_btn)
    IconFontTextView ifAddUserBtn;
    @BindView(R.id.ll_mute_btn)
    LinearLayout llMuteBtn;
    @BindView(R.id.ll_file_btn)
    LinearLayout llFileBtn;
    @BindView(R.id.ll_hang_up_btn)
    LinearLayout llHangUpBtn;
    @BindView(R.id.rl_menu)
    RelativeLayout rlMenu;
    @BindView(R.id.rl_full_screen)
    RelativeLayout rlFullScreen;
    @BindView(R.id.remote_video_view_container)
    FrameLayout container;
    @BindView(R.id.cb_call_mute_button)
    CheckBox cb_call_mute_button;
    @BindView(R.id.chronometer_layout)
    Chronometer chronometer_layout;
    @BindView(R.id.if_file)
    IconFontTextView if_file;

    private int unReadMsgNum = 0;//未读消息数量
    private int userNum = 0;//当前频道总人数
    private boolean timerFlag = true;

    private AgoraAPIOnlySignal mAgoraAPI;
    private RtcEngine mRtcEngine;
    private SurfaceView surfaceView;
    private int userId;
    private RemoteGuidanceBean remoteGuidanceBean;
    private BadgeHelper badgeHelper;

    private final int TIME = 1000;
    private int timingNum = 20;
    private Handler finishHandler = new Handler();
    private Runnable finishRunnable = new Runnable() {
        @Override
        public void run() {
            Logger.i("计时:"+timingNum);
            if(timingNum==1){
                Toasty.normal(RemoteGuidanceActivity.this,"网络信号不稳定,无法进行远程指导",Toast.LENGTH_LONG).show();
                finishHandler.removeCallbacks(finishRunnable);
                new Handler().postDelayed(new Runnable(){
                    public void run() {
                        finish();
                    }
                }, 2000);
            }else{
                timingNum--;
                finishHandler.postDelayed(finishRunnable, TIME);
            }
        }
    };

    @Override
    protected BasePresenter createPresenter() {
        return null;
    }

    @Override
    protected int provideContentViewId() {
        return R.layout.activity_remote_guidance;
    }

    @Override
    public void initView() {
        remoteGuidanceBean = (RemoteGuidanceBean) getIntent().getSerializableExtra("remoteGuidanceBean");
        userId = PrefUtils.getInt(this, PrefUtils.USER_USER_ID, -1);

        cb_call_mute_button.setOnCheckedChangeListener(oncheckChangeListerener);

        badgeHelper = new BadgeHelper(this)
                .setBadgeType(BadgeHelper.Type.TYPE_TEXT)
                .setBadgeOverlap(true, false);
        badgeHelper.bindToTargetView(llFileBtn);
        badgeHelper.setVisibility(View.GONE);


        Logger.i("远程指导...初始化...");
        checkPermissions();

    }
    private CompoundButton.OnCheckedChangeListener oncheckChangeListerener = new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            //静音
            mRtcEngine.muteLocalAudioStream(isChecked);
        }
    };




    private void checkPermissions() {
        RxPermissions permissions = new RxPermissions(this);
        permissions.setLogging(true);
        permissions.request(Manifest.permission.RECORD_AUDIO,
                        Manifest.permission.CAMERA,
                        Manifest.permission.WRITE_EXTERNAL_STORAGE)
                .subscribe(new Consumer<Boolean>() {
                    @Override
                    public void accept(Boolean aBoolean) throws Exception {
                        if (aBoolean) {
                            Logger.i("远程指导...权限...");
                            initAgoraEngineAndJoinChannel();
                        } else {
                            Toasty.warning(RemoteGuidanceActivity.this,"缺少远程指导必要权限").show();
                            finish();
                        }
                    }
                });



//        if (checkSelfPermission(Manifest.permission.RECORD_AUDIO, PERMISSION_REQ_ID_RECORD_AUDIO)
//                && checkSelfPermission(Manifest.permission.CAMERA, PERMISSION_REQ_ID_CAMERA)
//                && checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, PERMISSION_REQ_ID_STORAGE)) {
//            initAgoraEngineAndJoinChannel();
//        }
    }

    public boolean checkSelfPermission(String permission, int requestCode) {
        if (ContextCompat.checkSelfPermission(this,
                permission)
                != PackageManager.PERMISSION_GRANTED) {

            ActivityCompat.requestPermissions(this,
                    new String[]{permission},
                    requestCode);
            return false;
        }
        return true;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           @NonNull String permissions[], @NonNull int[] grantResults) {

        switch (requestCode) {
            case PERMISSION_REQ_ID_RECORD_AUDIO: {
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    checkSelfPermission(Manifest.permission.CAMERA, PERMISSION_REQ_ID_CAMERA);
                } else {
                    finish();
                }
                break;
            }
            case PERMISSION_REQ_ID_CAMERA: {
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, PERMISSION_REQ_ID_STORAGE);
                } else {
                    finish();
                }
                break;
            }
            case PERMISSION_REQ_ID_STORAGE: {
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    initAgoraEngineAndJoinChannel();
                } else {
                    finish();
                }
                break;
            }
        }
    }

    /**
     * 初始化声网
     */
    private void initAgoraEngineAndJoinChannel() {
        //初始化视频
        initializeAgoraEngine();     // 步骤1
        setupVideoProfile();         // 步骤2
        MyApp.the().setOnAgoraEngineInterface(this);
        setupLocalVideo();          // 步骤3
        joinChannel();               // 步骤4

        finishHandler.postDelayed(finishRunnable, TIME);
    }

//    @Override
//    protected void onNewIntent(Intent intent) {
//        super.onNewIntent(intent);
//        setupLocalVideo();          // 步骤3
//        joinChannel();               // 步骤4
//    }

    private void joinChannel() {
        //关闭使用本地摄像头设备
//        mRtcEngine.enableLocalVideo(false);
        //加入信令频道
        mAgoraAPI.channelJoin(remoteGuidanceBean.roomId);
        //加入视频频道
        Logger.i("加入房间号:"+remoteGuidanceBean.roomId);
        int i1 = mRtcEngine.leaveChannel();
        int i = mRtcEngine.joinChannel(null, remoteGuidanceBean.roomId, "Extra Optional Data", userId);// if you do not specify the uid, we will generate the uid for you
        Logger.i("加入频道码:"+i+"  离开频道:"+i1);
    }

    /**
     * 设置远程视频
     *
     * @param uid
     */
    // Tutorial Step 5
    private void setupRemoteVideo(int uid) {
//        if (container.getChildCount() >= 1) {
//            return;
//        }
//        surfaceView = RtcEngine.CreateRendererView(getBaseContext());
//
//        container.addView(surfaceView);
//        //调用 setupRemoteVideo() 方法设置本地看到的远端用户的视频视图
//        mRtcEngine.setupRemoteVideo(new VideoCanvas(surfaceView, VideoCanvas.RENDER_MODE_HIDDEN, uid));
//        surfaceView.setTag(uid); // 为了标记目标
        //开始计时
    }


    private void setupLocalVideo() {
//        SurfaceView surfaceView = RtcEngine.CreateRendererView(getBaseContext());
////        surfaceView.setZOrderMediaOverlay(true);
//        container.addView(surfaceView);
//        //设置本地视频视频
//        mRtcEngine.setupLocalVideo(new VideoCanvas(surfaceView, VideoCanvas.RENDER_MODE_HIDDEN, 0));
////        //镜像问题调用
////        mRtcEngine.setParameters("{\"che.video.localViewMirrorSetting\":\"disableMirror\"}");
//        mRtcEngine.startPreview();

        SurfaceView surfaceView = RtcEngine.CreateRendererView(getBaseContext());
        container.addView(surfaceView);
        mRtcEngine.setupLocalVideo(new VideoCanvas(surfaceView, VideoCanvas.RENDER_MODE_HIDDEN, 0));
        container.setVisibility(View.VISIBLE);
        mRtcEngine.startPreview();
        //转换摄像头
        mRtcEngine.switchCamera();
    }

    private void setupVideoProfile() {
        mRtcEngine.enableVideo();

        VideoEncoderConfiguration.VideoDimensions vd_1280x720 = VideoEncoderConfiguration.VD_1280x720;
        VideoEncoderConfiguration.FRAME_RATE frameRateFps15 = VideoEncoderConfiguration.FRAME_RATE.FRAME_RATE_FPS_15;
        int standardBitrate = VideoEncoderConfiguration.STANDARD_BITRATE;
        VideoEncoderConfiguration.ORIENTATION_MODE orientationModeAdaptive = VideoEncoderConfiguration.ORIENTATION_MODE.ORIENTATION_MODE_FIXED_LANDSCAPE;
        VideoEncoderConfiguration videoEncoderConfiguration = new VideoEncoderConfiguration(vd_1280x720, frameRateFps15, standardBitrate, orientationModeAdaptive);
        mRtcEngine.setVideoEncoderConfiguration(videoEncoderConfiguration);
    }

    private void initializeAgoraEngine() {
        mAgoraAPI = MyApp.the().getmAgoraAPI();
        mRtcEngine = MyApp.the().getmRtcEngine();
        if (mRtcEngine != null) {
            mRtcEngine.setLogFile("/sdcard/sdklog.txt");
        }
    }

    // Tutorial Step 10
    private void onRemoteUserVideoMuted(int uid, boolean muted) {
        SurfaceView surfaceView = (SurfaceView) container.getChildAt(0);

        Object tag = surfaceView.getTag();
        if (tag != null && (Integer) tag == uid) {
            surfaceView.setVisibility(muted ? View.GONE : View.VISIBLE);
        }
    }

    //对方离开
    private void onRemoteUserOffline(int uid) {
        endRemoteGuidance();
        Toasty.info(RemoteGuidanceActivity.this,"指导结束，对方已离开", Toast.LENGTH_LONG,false).show();
    }

    @Override
    protected void onResume() {
        super.onResume();
        addSignalingCallback();
    }



    //查询频道内信息
    private void queryChannelInfo(){
        ApiService.queryChannel(remoteGuidanceBean.roomId)
                .compose(RxSchedulersHelper.io_main())
                .compose(RxResultHelper.handleResult())
                .subscribe(new RxObserver<List<String>>() {
                    @Override
                    public void _onNext(List<String> list) {
                    }

                    @Override
                    public void _onError(String errorMessage) {

                    }
                });
    }

    @OnClick({R.id.ll_mute_btn, R.id.ll_file_btn, R.id.ll_hang_up_btn, R.id.rl_full_screen})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.ll_mute_btn://静音
                cb_call_mute_button.setChecked(!cb_call_mute_button.isChecked());
                break;
            case R.id.ll_file_btn://选择文件
                Intent intent = new Intent(this,FileListActivity.class);
                intent.putExtra("guideId", remoteGuidanceBean.guideId);
                unReadMsgNum=0;
                badgeHelper.setVisibility(View.GONE);
                startActivity(intent);

                break;
            case R.id.ll_hang_up_btn://挂断

                callOutHangup();

                break;
            case R.id.rl_full_screen://隐藏菜单
                rlMenu.setVisibility(rlMenu.getVisibility() == View.VISIBLE ? View.GONE : View.VISIBLE);
                break;
        }
    }

    private void callOutHangup() {
        new MaterialDialog.Builder(RemoteGuidanceActivity.this)
                .title("远程指导中，是否结束？")
                .positiveText("确认")
                .negativeText("取消")
                .onAny(new MaterialDialog.SingleButtonCallback() {
                    @Override
                    public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                        if (which == DialogAction.POSITIVE) {//确认
                            endRemoteGuidance();
                        } else if (which == DialogAction.NEGATIVE) {//取消
                            dialog.dismiss();
                        }

                    }
                }).show();
    }

    /**
     * 结束远程指导
     */
    private void endRemoteGuidance() {
        Map<String, String> map = new HashMap<>();
        map.put("operation", "2");//0 拒绝 1 接受 2结束
        map.put("roomId", remoteGuidanceBean.roomId);
        String json = new Gson().toJson(map);
        ApiService.inviteHandle(json)
                .compose(RxSchedulersHelper.io_main())
                .subscribe(new RxObserver<ResponseData>() {
                    @Override
                    public void _onSubscribe(Disposable d) {
                        super._onSubscribe(d);
                        showWaitingDialog("结束中...");
                    }

                    @Override
                    public void _onNext(ResponseData responseData) {
                        if (responseData.code == 0) {
                            Intent intent = new Intent(RemoteGuidanceActivity.this, GuideOverActivity.class);
                            intent.putExtra("guideId", Integer.parseInt(remoteGuidanceBean.guideId));
                            startActivity(intent);
                        } else {
                            Toasty.normal(RemoteGuidanceActivity.this,responseData.message).show();
                        }
                        hideWaitingDialog();
                        finish();

                    }
                    @Override
                    public void _onError(String errorMessage) {
                        Toasty.normal(RemoteGuidanceActivity.this,errorMessage).show();
                        hideWaitingDialog();
                        finish();
                    }
                });

    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (finishHandler != null) {
            finishHandler.removeCallbacks(finishRunnable);//移除定时关闭
        }

        mAgoraAPI.channelLeave(remoteGuidanceBean.roomId);
        if (mRtcEngine != null) {
            mRtcEngine.switchCamera();
            mRtcEngine.stopPreview();
            mRtcEngine.leaveChannel();//离开频道
        }
        mRtcEngine = null;
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    private void addSignalingCallback() {
        if (mAgoraAPI == null) {
            return;
        }

        mAgoraAPI.callbackSet(new AgoraAPI.CallBack() {

            /**
             * 收到频道消息回调
             * @param channelID 频道名
             * @param account 客户端定义的用户账号
             * @param uid 固定填 0
             * @param msg 消息正文
             */
            @Override
            public void onMessageChannelReceive(String channelID, final String account, final int uid, final String msg) {
                super.onMessageChannelReceive(channelID, account, uid, msg);
                Logger.i("接收到频道消息: account:"+account+" uid:"+uid+" msg:"+msg);
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        unReadMsgNum++;
                        if (badgeHelper.getVisibility() == View.GONE) {
                            badgeHelper.setVisibility(View.VISIBLE);
                        }
                        badgeHelper.setBadgeNumber(unReadMsgNum);//数字
                    }
                });
            }

            @Override
            public void onLogout(final int i) {
                Logger.i("Agora onLogout:"+i);
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        if (i == IAgoraAPI.ECODE_LOGOUT_E_KICKED) { // 账号其他地方登录
                        } else if (i == IAgoraAPI.ECODE_LOGOUT_E_NET) { // 网络问题
                            Toasty.normal(RemoteGuidanceActivity.this, "网络异常，可能无法收到对方文件！",Toast.LENGTH_LONG).show();
//                            new Handler().postDelayed(new Runnable(){
//                                public void run() {
//                                    finish();
//                                }
//                            }, 2000);
                        }
                    }
                });

            }

        });
    }


    @Override
    public void onFirstRemoteVideoDecoded(int uid, int width, int height, int elapsed) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                setupRemoteVideo(uid);
            }
        });
    }

    @Override
    public void onUserJoined(int uid, int elapsed) {
        Logger.i("远程加入频道:uid:"+uid);
        userNum++;
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (timerFlag) {
                    timerFlag = false;
                    finishHandler.removeCallbacks(finishRunnable);//移除定时关闭
                    chronometer_layout.setBase(SystemClock.elapsedRealtime());//计时器清零
                    chronometer_layout.start();
                }

            }
        });
    }

    @Override
    public void onUserOffline(int uid, int reason) {
        userNum--;
        if(userNum==0){
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    onRemoteUserOffline(uid);
                }
            });
        }
    }

    @Override
    public void onUserMuteVideo(int uid, boolean muted) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                onRemoteUserVideoMuted(uid, muted);
            }
        });
    }

    @Override
    public void onJoinChannelSuccess(String channel, int uid, int elapsed) {
        Logger.i("加入房间成功 uid:"+uid+" channel:"+channel);
    }

    @Override
    public void onError(int err) {
        Logger.i("声网错误:"+err);
    }
}
